"""
客户服务层
"""
from models import Guest, Reservation
from extension import db
from mappers.guest_mapper import GuestMapper
from .base_service import BaseService


class GuestService(BaseService):
    """客户业务逻辑"""
    
    def __init__(self):
        super().__init__(Guest)
        self.mapper = GuestMapper()
    
    def get_guests_with_filters(self, page=1, per_page=10, name=None, phone=None, vip_level=None):
        """获取客户列表（支持多条件过滤）"""
        from sqlalchemy import or_
        
        query = Guest.query
        
        if name:
            query = query.filter(Guest.name.like(f'%{name}%'))
        if phone:
            query = query.filter(Guest.phone.like(f'%{phone}%'))
        if vip_level is not None:
            query = query.filter(Guest.vip_level == vip_level)
        
        return query.paginate(page=page, per_page=per_page, error_out=False)
    
    def create_guest(self, name, phone, id_number, email=None, address=None, vip_level=0, total_spent=0):
        """创建客户"""
        # 检查身份证号是否已存在
        if Guest.query.filter_by(id_number=id_number).first():
            raise ValueError('身份证号已存在')
        
        guest = Guest(
            name=name,
            phone=phone,
            id_number=id_number,
            email=email or '',
            address=address or '',
            vip_level=vip_level,
            total_spent=total_spent
        )
        db.session.add(guest)
        db.session.commit()
        return guest
    
    def update_guest(self, guest_id, **data):
        """更新客户信息"""
        guest = self.get_by_id(guest_id)
        if not guest:
            return None
        
        # 检查身份证号是否重复
        if 'id_number' in data and data['id_number'] != guest.id_number:
            if Guest.query.filter(Guest.id_number == data['id_number']).first():
                raise ValueError('身份证号已被占用')
        
        for key, value in data.items():
            if hasattr(guest, key) and value is not None:
                setattr(guest, key, value)
        
        db.session.commit()
        return guest
    
    def delete_guest(self, guest_id):
        """删除客户（检查是否有关联预订）"""
        guest = self.get_by_id(guest_id)
        if not guest:
            return False
        
        # 检查是否存在关联的预订记录
        if Reservation.query.filter_by(guest_id=guest_id).first():
            raise ValueError('该客户存在关联的预订记录，无法删除')
        
        db.session.delete(guest)
        db.session.commit()
        return True
    
    def get_guest_statistics(self, guest_id):
        """获取客户统计信息"""
        guest = self.get_by_id(guest_id)
        if not guest:
            return None
        
        reservations = Reservation.query.filter_by(guest_id=guest_id).all()
        
        return {
            'total_reservations': len(reservations),
            'total_spent': float(guest.total_spent),
            'vip_level': guest.vip_level,
            'last_reservation': max([r.check_out for r in reservations]) if reservations else None
        }
    
    def get_guests_paginated_dto(self, page=1, per_page=10, name=None, phone=None, vip_level=None):
        """获取客户列表（返回DTO）"""
        paginated = self.get_guests_with_filters(page, per_page, name, phone, vip_level)
        return {
            'list': [self.mapper.to_dict(guest) for guest in paginated.items],
            'total': paginated.total,
            'page': paginated.page,
            'pageSize': paginated.per_page,
            'pages': paginated.pages
        }
    
    def get_guest_dto(self, guest_id):
        """获取客户详情（返回DTO）"""
        guest = self.get_by_id(guest_id)
        return self.mapper.to_dict(guest) if guest else None
    
    def create_guest_dto(self, name, phone, id_number, email=None, address=None, vip_level=0, total_spent=0):
        """创建客户（返回DTO）"""
        guest = self.create_guest(name, phone, id_number, email, address, vip_level, total_spent)
        return self.mapper.to_dict(guest)
    
    def update_guest_dto(self, guest_id, **data):
        """更新客户（返回DTO）"""
        guest = self.update_guest(guest_id, **data)
        return self.mapper.to_dict(guest) if guest else None
